Skip to content

03 内容过滤器 - grep

grep 指令

  • grep 用于在文件中搜索匹配指定模式的文本行(关键信息提取)。
  • grep 的名字来源于“global regular expression print”的缩写。它使用正则表达式来匹配模式,并在文件中搜索这些模式。
bash
  ~ top | grep %Cpu # 只显示 top 输出中包含 %Cpu 的内容
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu(s):  0.3 us,  0.5 sy,  0.0 ni, 99.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu(s):  0.3 us,  0.7 sy,  0.0 ni, 98.8 id,  0.1 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu(s):  0.3 us,  1.0 sy,  0.0 ni, 98.4 id,  0.2 wa,  0.0 hi,  0.1 si,  0.0 st

grep 的两种使用方式

bash
grep [parameters] [file or dir]
  • grep error kernel.log: 在 kernel.log 文件中查找 error 这个字符串
  • grep "^warn*" kernel.log: 在 kernel.log 文件中查找 warn 开头的内容
bash
[command] | grep [parameters]
  • cat kernel.log | grep error: 效果与 grep error kernel.log 一致

grep 常用参数

参数描述
-i (--ignore-case)忽略大小写进行匹配(默认大小写敏感)
-v (--invert-match)反向查找,只打印不匹配的行
-n (--line-number)显示匹配行的行号
-r (--recursive)递归查找子目录中的文件
`-l (--file-with-matches)只打印匹配的文件名
-c (--count)只打印匹配的行数
-e (--regexp)多关键字匹配
参数描述
-i忽略大小写差异
-v反转匹配,显示不匹配的行
-r-R递归搜索目录中的所有文件
-l仅显示包含匹配模式的文件名
-n在匹配的行前显示行号
-c仅显示匹配的行数
-o仅显示匹配的部分
-E使用扩展正则表达式(等同于 egrep
-FPATTERN 视为固定字符串列表(等同于 fgrep
-w只匹配整个单词
-A NUM匹配行及其后 NUM
-B NUM匹配行及其前 NUM
-C NUM匹配行及其前后 NUM

grep 与正则表达式的结合

命令描述
`cat kernel.loggrep "^warning"`
`cat kernel.loggrep "success$"`
`cat kernel.loggrep "Method[0-3]"`
`cat kernel.loggrep "[wW]arning"`
`cat kernel.loggrep "^2023.error$"`

grep 使用示例

功能命令说明
基本搜索grep 'pattern' filenamefilename 文件中搜索包含字符串 pattern 的行。
忽略大小写grep -i 'pattern' filenamefilename 文件中搜索包含字符串 pattern(忽略大小写)的行。
递归搜索grep -r 'pattern' /path/to/directory在指定目录及其子目录中的所有文件中搜索包含字符串 pattern 的行。
显示行号grep -n 'pattern' filenamefilename 文件中搜索包含字符串 pattern 的行,并显示行号。
显示匹配文件名grep -l 'pattern' /path/to/directory/*显示包含字符串 pattern 的文件名。
计数匹配行数grep -c 'pattern' filename显示 filename 文件中包含字符串 pattern 的行数。
只显示匹配的部分grep -o 'pattern' filenamefilename 文件中只显示匹配的部分,而不是整行。
反向匹配grep -v 'pattern' filename显示 filename 文件中不包含字符串 pattern 的行。
上下文行grep -C 3 'pattern' filenamefilename 文件中搜索包含字符串 pattern 的行,并显示每个匹配行的前后 3 行。
使用扩展正则表达式grep -E 'pattern1|pattern2' filename使用扩展正则表达式在 filename 文件中搜索包含 pattern1pattern2 的行。

grep 常用命令

  1. 借助管道命令,从数万行日志中过滤信息。 dmesg | grep "^2023" | grep error -i | grep "[0-9]" | grep -v "eth"

    • dmesg: dmesg 命令显示 Linux 内核的环形缓冲区信息,这些信息包括系统启动时的日志以及之后系统运行时发生的硬件相关事件。
    • grep "^2023": grep 是用于搜索文本的工具。"^2023" 是一个正则表达式,表示匹配以 "2023" 开头的行。这意味着这个 grep 命令将只保留那些行首包含 "2023"dmesg 输出。
    • grep error -i: -i 选项使得 grep 在搜索时不区分大小写。因此,这个命令会匹配所有包含 "error" (无论大小写)的行。
    • grep "[0-9]": 这个命令将只保留那些包含至少一个数字的行。
    • grep -v "eth": -v 选项告诉 grep 输出不匹配模式的行。因此,这个命令将排除所有包含 "eth" 字符串的行。

    综合以上步骤,整个命令链的作用是:从 dmesg 的输出中找到所有以 "2023" 开头,包含 "error" (不区分大小写),至少有一个数字,但不包含 "eth" 字符串的行。

  2. dmesg | grep -e "etho" -e "Eth0" 等价于 dmesg | grep -E "eth0|Eth0

    • -e 选项允许 grep 指定多个匹配模式。在这个例子中,有两个模式:"eth0""Eth0"
    • 这个命令将匹配所有包含 "eth0""Eth0" 字符串的行。
  3. 递归查找特定内容:grep -nr "kernel"。在当前路径下递归查找包含 kernel 的文件名,同时输出文字所在行号。

  4. 忽略大小写查找:cat kernel.log | grep warning -i。查找 kernel.log 中包含 warning 的行内容,不区分大小写。即若存在 Warning/WARNING,亦可被查找到。

grep 应用实例

在 Linux 文件系统下,有一个 .so 库,位置位于 /lib/lib64 文件夹下,文件名里面带有 z,使用 grep 命令进行查找。

  • 使用 ls + grep 进行查找:ls -lha /lib*/* | grep z | grep so | grep "^-"

    • ls -lha /lib*/*:列出 /lib/lib64 目录及其子目录中的所有文件和目录的详细信息。

    • | grep z:过滤出文件名中包含字母 'z' 的条目。

    • | grep so:进一步过滤出文件名中包含字符串 so 的条目。

    • | grep "^- ":最终过滤出以 - 开头的条目,即普通文件,而不是目录或其他类型的文件。

      字符文件类型
      -普通文件
      d目录
      l符号链接 (symlink)
      c字符设备文件
      b块设备文件
      p命名管道 (FIFO)
      s套接字 (socket)
  • 使用 find + grep 进行查找:find /lib /lib64 -type f -name '*.so*' | grep 'z'

    • find /lib /lib64 -type f -name '*.so*':在 /lib/lib64 目录下递归查找所有符合条件的文件:
    • -type f:仅查找文件。
    • -name '*.so*':查找文件名包含 .so 的文件(包括 .so.so.x 等等)。
  • | grep 'z':将 find 命令的输出通过管道传递给 grep,然后过滤出文件名中包含字母 'z' 的文件。